#include "Logger.h"

#include <cstdio>
#include <cstdarg>
#include <cstring>
#include <cerrno>

Logger& Logger::getInstance()
{
	static Logger instance;
	return instance;
}

Logger::Logger() :
	logFile_(NULL)
{
	pthread_mutex_init(&mutex_, NULL);
}

Logger::~Logger()
{
	pthread_mutex_destroy(&mutex_);
	if(logFile_)
		fclose(logFile_);
}		

void Logger::logDlm(Level level, const char* format, ...) 
{
	va_list args;
	
	char *level_txt;
	char errno_info[256];
	int last_errno = errno;
	
	va_start(args, format);	
	
	switch(level)
	{
		case INFO:
			level_txt = (char *)"INFO";
			break;
		case WARN:
			level_txt = (char *)"WARNING";
			break;
		case ERRNO:
		case ERROR:
			level_txt = (char *)"ERROR";					
	}
	
	pthread_mutex_lock(&mutex_);	
		
	logPrint(" * DLM %-8s: ", level_txt);

	logVPrint(format, args);

	
	if(level == ERRNO)
	{
		logPrint(" (%s)", strerror_r(last_errno, 
				errno_info, sizeof(errno_info)));
	}
		
	logPrint("\n");
	pthread_mutex_unlock(&mutex_);		
	
	va_end(args);		
}

void Logger::logProcess(int pid, const char* message) 
{	
	pthread_mutex_lock(&mutex_);
		
	logPrint(" > PID %-8u: %s\n", pid, message);	
	
	pthread_mutex_unlock(&mutex_);					
}	


bool Logger::setLogFile(const char file_path[])
{
	pthread_mutex_lock(&mutex_);
	logFile_ = fopen(file_path, "w");
	pthread_mutex_unlock(&mutex_);	

	return logFile_ != NULL;
}

void Logger::logPrint(const char* format, ...)
{
	va_list args;
	va_start(args, format);	
	
	logVPrint(format, args);
		
	va_end(args);
}


void Logger::logVPrint(const char* format, va_list &args)
{
	va_list backup;
	va_copy(backup, args);
	vfprintf(stderr, format, backup);
	if(logFile_)
	{
		va_copy(backup, args);
		vfprintf(logFile_, format, backup);
		fflush(logFile_);
	}
}

